const log = console.log.bind(console)

const e = function(selector) {
    return document.querySelector(selector)
}

const es = function(selector) {
    return document.querySelectorAll(selector)
}
const mineCellTemplate = function(n) {
    let t = `<div class="mine-cell">${n}</div>`
    return t
}
const mineLineTemplate = function(arr) {
    let cells = ''
    for (let i = 0; i < arr.length; i++) {
        cells += mineCellTemplate(arr[i])
    }
    let line = `<div class="mine-line">${cells}</div>`
    return line
}
const mineMapTemplate = function(arr) {
    let lines = ''
    for (let i = 0; i < arr.length; i++) {
        lines += mineLineTemplate(arr[i])
    }
    let map = `<div id="id-div-map">${lines}</div>`
    return map
}

const loadMineMap = function(arr) {
    let mineMapContainer = e('#id-div-container')
    let t = mineMapTemplate(arr)
    mineMapContainer.insertAdjacentHTML('beforeend', t)
}
const findMap = function() {
    let mineMapContainer = e('#id-div-container')
    return mineMapContainer.querySelector('#id-div-map')
}
const removeMineMap = function() {
    let map = findMap()
    map.remove()
}
const mineClickListener = function(event) {
    let target = event.target
    if (target.classList.contains('mine-cell')) {
        let c = cellPosition(target)
        openAround(c[0], c[1])
        log('c', c)
        log('target.innerHTML', target.innerHTML)
    }
}
const bindEventDelegate = function() {
    let container = e('#id-div-container')
    container.addEventListener('click', mineClickListener)
}
const removeEventDelegate = function() {
    let container = e('#id-div-container')
    container.removeEventListener('click', mineClickListener)
}
const openCell = function(i, j) {
    let cell = findCell(i, j)
    let text = cell.innerHTML
    if (text !== '9') {
        cell.classList.add('open')
    }
    if (text === '0') {
        cell.classList.add('open-zero')
    } if (text === '9') {
        gameOver()
    }
}
const isOpen = function(element) {
    return element.classList.contains('open')
}
const coordinateIsValid = function(i, j) {
    let map = findMap()
    let len = map.children.length
    let isValid = i >= 0 && i < len && j >= 0 && j < len
    return isValid
}
const travelAround = function(x, y, fn) {
    for (let i = x - 1; i < x + 2; i++) {
        for (let j = y - 1; j < y + 2; j++) {
            if (coordinateIsValid(i, j) && !isOpen(findCell(i, j))) {
                fn(i, j)
            }
        }
    }
}
const openAround = function(x, y) {
    let cell = findCell(x, y)
    let text = cell.innerHTML
    if (text !== '0') {
        openCell(x, y)
    } else {
        openCell(x, y)
        travelAround(x, y, openAround)
    }
}
const findCell = function(x, y) {
    let map = findMap()
    let cell = map.children[x].children[y]
    return cell
}
const cellPosition = function(element) {
    let lines = es('.mine-line')
    for (let i = 0; i < lines.length; i++) {
        for (let j = 0; j < lines[i].children.length; j++) {
            let child = lines[i].children[j]
            if (element === child) {
                return [i, j]
            }
        }
    }
}

const mineCoordinate = function() {
    let map = findMap()
    let result = []
    let lines = map.children

    for (let i = 0; i < lines.length; i++) {
        for (let j = 0; j < lines[i].children.length; j++) {
            let cell = lines[i].children[j]
            if (cell.innerHTML === '9') {
                result.push([i, j])
            }
        }
    }
    log('result', result)
    return result
}
const isMine = function(cell) {
    return cell.innerHTML === '9'
}
const overCell = function() {
    let mineXYs = mineCoordinate()
    for (let i = 0; i < mineXYs.length; i++) {
        let x = mineXYs[i][0]
        let y = mineXYs[i][1]
        let mine = findCell(x, y)
        mine.classList.add('over')
        mine.classList.add('open')
    }
}

const gameOver = function() {
    overCell()
    removeEventDelegate()
}
const bindEvents = function() {
    bindEventDelegate()
    bindLevelsEvent()
}
const configuration = function() {
    let levels = {
        primary: [9, 10],
        intermediate: [16, 40],
        senior: [22, 99],
    }
    return levels
}
const configMineMap = function(len, mines) {
    let arr = zeroSquare(len)
    let markedArr = markedSquare(zeroSquareAdd9(arr, mines))
    removeMineMap()
    loadMineMap(markedArr)
    bindEventDelegate()

}
const bindLevelsEvent = function() {
    let levels = e('#id-div-levels')
    levels.addEventListener('click', function(event) {
        let target = event.target
        let configs = configuration()
        let config = configs[target.id]
        configMineMap(config[0], config[1])
    })
}
const initMineMap = function() {
    let arr = zeroSquare(9)
    let markedArr = markedSquare(zeroSquareAdd9(arr, 10))
    loadMineMap(markedArr)
}
const __main = function() {
    initMineMap()
    bindEvents()
}
__main()

